package com.xckj.cycling.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.inuker.bluetooth.library.Constants;
import com.inuker.bluetooth.library.connect.listener.BleConnectStatusListener;
import com.inuker.bluetooth.library.connect.options.BleConnectOptions;
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.xckj.cycling.bean.BleDevStatusBean;
import com.xckj.cycling.bean.DevDataBean;
import com.xckj.cycling.bean.common.EventBusBean;
import com.xckj.cycling.bean.common.EventTag;
import com.xckj.cycling.bluetooth.BluetoothClientManager;
import com.xckj.cycling.context.AppContext;
import com.xckj.cycling.global.BleConstant;
import com.xckj.cycling.presenter.ReportDeviceDataPresenter;
import com.xckj.cycling.utils.DetectUtil;
import com.xckj.cycling.viewmodel.BleViewModel;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.UUID;

import androidx.lifecycle.ViewModelProvider;

import static com.inuker.bluetooth.library.Code.REQUEST_SUCCESS;
import static com.inuker.bluetooth.library.Constants.STATUS_DEVICE_CONNECTED;

/**
 * 蓝牙连接服务.
 */
public class BleConnService extends Service {

    private static final String TAG = BleConnService.class.getSimpleName();
    private boolean isThreadRunFlag = false;// 服务运行标记
    private BleViewModel bleViewModel;
    private DevDataBean devDataBean;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);// 注册Eventbus
        isThreadRunFlag = true;
        bleViewModel = new ViewModelProvider(AppContext.globalContext()).get(BleViewModel.class);
        devDataBean = new DevDataBean();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isThreadRunFlag = false;
        EventBus.getDefault().unregister(this);// 反注册Eventbus
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageEventBus(EventBusBean eventBusBean) {
        switch (eventBusBean.getTag()) {
            case EventTag_conn_ble:
                doConn((String) eventBusBean.getData());
                break;
            case EventTag_disconn_ble:
                String macaddress3 = (String) eventBusBean.getData();
                BluetoothClientManager.getBluetoothClient().disconnect(macaddress3);
                break;
        }
    }

    // 被动连接蓝牙
    private void doConn(String macaddress) {
        int connectStatus = BluetoothClientManager.getBluetoothClient().getConnectStatus(macaddress);
        if (connectStatus == Constants.STATUS_DEVICE_CONNECTED || connectStatus == Constants.STATUS_DEVICE_CONNECTING) {
//            showMessage("该设备已被连接");
            return;
        }
        BluetoothClientManager.getBluetoothClient().stopSearch();
        BluetoothClientManager.getBluetoothClient().disconnect(macaddress);
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3) // 连接如果失败重试3次
                .setConnectTimeout(5000) // 连接超时30s
                .setServiceDiscoverRetry(3)  // 发现服务如果失败重试3次
                .setServiceDiscoverTimeout(10000)  // 发现服务超时20s
                .build();
        // 设置状态监听，便于主动反馈状态
        BluetoothClientManager.getBluetoothClient().registerConnectStatusListener(macaddress, new BleConnectStatusListener() {
            @Override
            public void onConnectStatusChanged(String mac, int status) {
                bleViewModel.setBleConnStatus(new BleDevStatusBean(macaddress, status));
            }
        });
        BluetoothClientManager.getBluetoothClient().connect(macaddress, options, (code, profile) -> {
            if (code == REQUEST_SUCCESS) {
                EventBus.getDefault().post(new EventBusBean(EventTag.EventTag_service_ble_conn_success));
                Log.d(TAG, "设备已成功连接");
                bleViewModel.setBleConnStatus(new BleDevStatusBean(macaddress, STATUS_DEVICE_CONNECTED));
                notifyData(macaddress);
            } else {
                EventBus.getDefault().post(new EventBusBean(EventTag.EventTag_service_ble_conn_fail));
                Log.d(TAG, "设备连接失败");
                // 连接失败 自定义状态码为5
                bleViewModel.setBleConnStatus(new BleDevStatusBean(macaddress, 5));
            }
        });
    }

    private void notifyData(String MAC) {
        BluetoothClientManager.getBluetoothClient().notify(MAC, BleConstant.SERVICE_UUID, BleConstant.NOTICE_CHARACTERISTIC_UUID, new BleNotifyResponse() {
            @Override
            public void onNotify(UUID service, UUID character, byte[] value) {
                Log.d(TAG, DetectUtil.bytesToHexString(value));
                parseData(MAC, value);
            }

            @Override
            public void onResponse(int code) {
                if (code == REQUEST_SUCCESS) {

                }
            }
        });
    }

    private void writeData(String MAC, byte[] bytes) {
        BluetoothClientManager.getBluetoothClient().writeNoRsp(MAC, BleConstant.SERVICE_UUID, BleConstant.WRITE_CHARACTERISTIC_UUID, bytes, new BleWriteResponse() {
            @Override
            public void onResponse(int code) {

            }
        });
    }

    // 解析单帧数据
    private void parseData(String mac, byte[] value) {
        Log.d(TAG, DetectUtil.bytesToHexString(value));
        if (!DetectUtil.checkDevData(value)) {
            return;
        }
        byte[] bytes = DetectUtil.getSomeByteData(value, 4, value[3]);
        switch (value[2]) {
            case (byte) 0xA0:
                String askStr = "3A0DA00000000D0A";
                writeData(mac, DetectUtil.HexString2Bytes(askStr));
                break;
            case (byte) 0xA1:
                // 车辆行使总里程（单位1KM）
                // 3A0AA102 0700 0700 0D0A
                byte[] totalMileageBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setTotalMileage(DetectUtil.twoByteArrayToInt(totalMileageBytes));
                break;
            case (byte) 0xA2:
                // singleMileage;// 车辆行驶单次里程(单位0.1KM)
                byte[] singleMileageBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setSingleMileage(DetectUtil.twoByteArrayToInt(singleMileageBytes));
                break;
            case (byte) 0xA3:
                // residueModel;// 车辆当前可骑行距离(单位1KM)
                byte[] residueModelBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setResidueModel(DetectUtil.twoByteArrayToInt(residueModelBytes));
                break;
            case (byte) 0xA5:
                // 车辆当前助力档位（eg.1档）
                byte[] curGearAssistanceBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setCurGearAssistance(DetectUtil.byteToInt(curGearAssistanceBytes[0]));
                break;
            case (byte) 0xA6:
                // 车辆当前行使速度（单位0.1km/h）
                byte[] curSpeedBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setCurSpeed(DetectUtil.twoByteArrayToInt(curSpeedBytes));
                break;
            case (byte) 0xA7:
                // avrSpeed;// 车辆平均速度（单位0.1km/h）
                byte[] avrSpeedBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setAvrSpeed(DetectUtil.twoByteArrayToInt(avrSpeedBytes));
                break;
            case (byte) 0xA8:
                // maxSpeed;// 车辆最大速度（单位0.1km/h）
                byte[] maxSpeedBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setMaxSpeed(DetectUtil.twoByteArrayToInt(maxSpeedBytes));
                break;
            case (byte) 0xB3:
                // battery;// 电池电量百分比（0-100%）
                byte[] batteryBytes = DetectUtil.changeBytes(bytes);
                devDataBean.setBattery(DetectUtil.byteToInt(batteryBytes[0]));
                ReportDeviceDataPresenter deviceAddedPresenter = new ReportDeviceDataPresenter();
                deviceAddedPresenter.reportDeviceData("",
                        devDataBean.getCurGearAssistance() + "",
                        devDataBean.getCurSpeed() + "",
                        devDataBean.getAvrSpeed() + "",
                        devDataBean.getMaxSpeed() + "",
                        devDataBean.getBattery() + "",
                        devDataBean.getTotalMileage() + "",
                        devDataBean.getResidueModel() + "",
                        devDataBean.getSingleMileage() + "",
                        mac);
                break;
        }
    }

}